-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Lazy render logs to increase performance #25046
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
| App Name | Jetpack | |
| Configuration | Release-Alpha | |
| Build Number | 30072 | |
| Version | PR #25046 | |
| Bundle ID | com.jetpack.alpha | |
| Commit | a5a8e3d | |
| Installation URL | 3ltjmldc9cpu0 |
|
| App Name | WordPress | |
| Configuration | Release-Alpha | |
| Build Number | 30072 | |
| Version | PR #25046 | |
| Bundle ID | org.wordpress.alpha | |
| Commit | a5a8e3d | |
| Installation URL | 2f1s3gdirqra8 |
dcalhoun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This tested well for me. 🎉 Thanks!
I'll note these changes do not impact the experimental "New Support" feature. The logic for that resides in Modules/Sources/Support/UI/Application Logs/ActivityLogDetailView.swift. Claude suggested the following for applying the lazy render optimization there. I did not test the suggestion, nor do we necessarily need to address it in this PR, but I share it for additional context.
New Support lazy render optimization diff
diff --git a/Modules/Sources/Support/UI/Application Logs/ActivityLogDetailView.swift b/Modules/Sources/Support/UI/Application Logs/ActivityLogDetailView.swift
index 88f8f48ced..748c81f075 100644
--- a/Modules/Sources/Support/UI/Application Logs/ActivityLogDetailView.swift
+++ b/Modules/Sources/Support/UI/Application Logs/ActivityLogDetailView.swift
@@ -8,14 +8,14 @@ struct ActivityLogDetailView: View {
enum ViewState: Equatable {
case loading
- case loaded(String, isSharing: Bool)
+ case loaded([String], isSharing: Bool)
case error(Error)
static func == (lhs: ActivityLogDetailView.ViewState, rhs: ActivityLogDetailView.ViewState) -> Bool {
return switch (lhs, rhs) {
case (.loading, .loading): true
- case (.loaded(let lhscontent, let lhsisSharing), .loaded(let rhscontent, let rhsisSharing)):
- lhscontent == rhscontent && lhsisSharing == rhsisSharing
+ case (.loaded(let lhsLines, let lhsisSharing), .loaded(let rhsLines, let rhsisSharing)):
+ lhsLines == rhsLines && lhsisSharing == rhsisSharing
case (.error, .error): true
default: false
}
@@ -38,8 +38,8 @@ struct ActivityLogDetailView: View {
switch self.state {
case .loading:
self.loadingView
- case .loaded(let content, _):
- self.loadedView(content: content)
+ case .loaded(let lines, _):
+ self.loadedView(lines: lines)
case .error(let error):
self.errorView(error: error)
}
@@ -54,11 +54,11 @@ struct ActivityLogDetailView: View {
}
}
.sheet(isPresented: self.$isDisplayingShareSheet, onDismiss: {
- guard case .loaded(let content, _) = self.state else {
+ guard case .loaded(let lines, _) = self.state else {
return
}
- self.state = .loaded(content, isSharing: false)
+ self.state = .loaded(lines, isSharing: false)
}, content: {
ActivityLogSharingView(applicationLog: applicationLog) {
AnyView(erasing: Text("TODO: A new support request with the application log attached"))
@@ -87,15 +87,21 @@ struct ActivityLogDetailView: View {
}
@ViewBuilder
- func loadedView(content: String) -> some View {
+ func loadedView(lines: [String]) -> some View {
ScrollView {
- VStack(alignment: .leading) {
- TextEditor(text: .constant(content))
- .font(.system(.body, design: .monospaced))
- .fixedSize(horizontal: false, vertical: true)
- .scrollDisabled(true)
- .padding()
+ LazyVStack(alignment: .leading, spacing: 0) {
+ logLinesContent(lines: lines)
}
+ .font(.system(.body, design: .monospaced))
+ .padding()
+ }
+ }
+
+ @ViewBuilder
+ private func logLinesContent(lines: [String]) -> some View {
+ ForEach(Array(lines.enumerated()), id: \.offset) { _, line in
+ Text(line)
+ .frame(maxWidth: .infinity, alignment: .leading)
}
}
@@ -110,19 +116,22 @@ struct ActivityLogDetailView: View {
private func loadLogContent() async {
do {
let content = try await self.dataProvider.readApplicationLog(applicationLog)
+ let lines = content
+ .split(separator: "\n", omittingEmptySubsequences: false)
+ .map(String.init)
- self.state = .loaded(content, isSharing: false)
+ self.state = .loaded(lines, isSharing: false)
} catch {
self.state = .error(error)
}
}
private func startSharing() {
- guard case .loaded(let content, _) = self.state else {
+ guard case .loaded(let lines, _) = self.state else {
return
}
- state = .loaded(content, isSharing: true)
+ state = .loaded(lines, isSharing: true)
}
}
WordPress/Classes/ViewRelated/Me/Help & Support/SupportActivityDetailsView.swift
Outdated
Show resolved
Hide resolved
Thanks @dcalhoun! I wasn't even aware of that view. I applied the same functionality to it and noticed a massive difference in memory usage when viewing a log:
|
|
dcalhoun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested well for me—both the legacy and new support UI. 🚀
I applied the same functionality to it and noticed a massive difference in memory usage when viewing a log:
Whoa!







Description
Instead of rendering one potentially massive
Textview, lazy load it via array of strings. Logs on my device were large enough to crash the app due to the main thread watchdog.lazy_logs.mp4
Testing instructions
Legacy support view
Ensure new support experience feature is disabled.
New support view
Ensure new support experience feature is enabled.